home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gcore / sun4.md / process.c < prev   
Encoding:
C/C++ Source or Header  |  1992-07-02  |  9.5 KB  |  365 lines

  1. /* 
  2.  * process.c --
  3.  *
  4.  *    Routines for finding and manipulating processes for the
  5.  *    gcore program.
  6.  *
  7.  * Copyright 1988 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /sprite/src/cmds/gcore/RCS/process.c,v 1.4 91/10/25 10:28:36 jhh Exp $ SPRITE (Berkeley)";
  19. #endif not lint
  20.  
  21.  
  22. #include <ctype.h>
  23. #include <option.h>
  24. #include <status.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <signal.h>
  29. #include <sys/types.h>
  30. #include <sys/file.h>
  31. #include <proc.h>
  32. #include <vm.h>
  33.  
  34. #include "gcore.h"
  35.  
  36.  
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  *  FindProcess --
  41.  *
  42.  *      Find the process and argument string of the specified process.
  43.  *
  44.  * Results:
  45.  *    The process state.
  46.  *
  47.  *
  48.  * Side effects:
  49.  *      The none.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53.  
  54. int
  55. FindProcess(pid,argString,segSizePtr,sigStatePtr)
  56.     int        pid;        /* Process ID to locate. */
  57.     char    *argString;    /* Area to place argument string of
  58.                  * the specified process. */
  59.     int        *segSizePtr;    /* Array to store segment size in. */
  60.     int        *sigStatePtr;   /* Out: State of the signal masks. 
  61.                  * In: The signal to check. */
  62. {
  63.     int  pcbsUsed;
  64.     ReturnStatus status;
  65.     Proc_PCBInfo    pcb;
  66.     Proc_PCBInfo    *pcbPtr;
  67.     Proc_PCBArgString    pcbArgString;
  68.     int            procState;
  69.  
  70.     /*
  71.      * Find the PCB of the specifed process.
  72.      */
  73.     procState = NOT_FOUND_STATE;
  74.     pcbPtr = &pcb;
  75.     status = Proc_GetPCBInfo(Proc_PIDToIndex(pid),
  76.                  Proc_PIDToIndex(pid), PROC_MY_HOSTID,
  77.                  sizeof(Proc_PCBInfo),
  78.                  pcbPtr, &pcbArgString, &pcbsUsed);
  79.     if (status != SUCCESS) {
  80.     if (debug) {
  81.         (void) fprintf(stderr, "Proc_GetPCBInfo for pid 0x%x error: %s",pid,
  82.             Stat_GetMsg(status));
  83.     }
  84.     return procState;
  85.     }
  86.  
  87.     /*
  88.      * The process we got info for may not be the one that was
  89.      * requested (different generation numbers);  check to be sure.
  90.      */
  91.     if (pid != pcbPtr->processID) {
  92.     if (debug) {
  93.         (void) fprintf(stderr,
  94.             "Proc_GetPCBInfo: looking for 0x%x but found 0x%x\n",
  95.            pid,pcbPtr->processID);    
  96.         }
  97.         return procState;
  98.     }
  99.     /*
  100.      * Check the process state.
  101.      */
  102.     switch (pcbPtr->state) {
  103.     case PROC_SUSPENDED: {
  104.     procState = (pcbPtr->genFlags & (PROC_DEBUGGED | PROC_ON_DEBUG_LIST)) ?
  105.                 DEBUG_STATE : 
  106.                 SUSPEND_STATE;
  107.     break;
  108.         }
  109.     case PROC_RUNNING:
  110.     case PROC_READY:
  111.     case PROC_WAITING: {
  112.     procState = RUN_STATE;
  113.     break;
  114.         }
  115.     default:
  116.     procState = UNKNOWN_STATE;
  117.     }
  118.  
  119.     /*
  120.      * Copy the argument string to return it.
  121.      */
  122.     if (argString != NULL) {
  123.     char    *ap = pcbArgString.argString;
  124.     (void) strncpy(argString,ap,MAX_ARG_STRING_SIZE-1);
  125.     argString[MAX_ARG_STRING_SIZE-1] = 0;
  126.     if (debug) {
  127.         (void) fprintf(stderr,"FindProcess: Argument string \"%s\"\n",ap);
  128.     }
  129.    }
  130.    /*
  131.     * Lookup the segment size from the virtual memory system.
  132.     */
  133.     if (segSizePtr != (int *) 0) {
  134.       Vm_SegmentInfo     segBuf[VM_NUM_SEGMENTS];
  135.       int                 pagesize = getpagesize();
  136.  
  137.       status = Vm_GetSegInfo(pcbPtr, 0, sizeof(Vm_SegmentInfo),
  138.                      &(segBuf[1]));
  139.       if (status != SUCCESS) {
  140.         if(debug) {
  141.         (void) fprintf(stderr, 
  142.             "Couldn't read segment info for pid %x: %s\n",
  143.             pcbPtr->processID, Stat_GetMsg(status));
  144.         }
  145.       }
  146.       segSizePtr[TEXT_SEG] = segBuf[VM_CODE].numPages*pagesize;
  147.       segSizePtr[DATA_SEG] = segBuf[VM_HEAP].numPages*pagesize;
  148.       segSizePtr[STACK_SEG] = segBuf[VM_STACK].numPages*pagesize;
  149.     }
  150.  
  151.    if (sigStatePtr != (int *) 0) {
  152.     int    spriteSig;
  153.     (void) Compat_UnixSignalToSprite(*sigStatePtr,&spriteSig);
  154.     if (pcbPtr->sigActions[spriteSig] == SIG_IGNORE_ACTION) {
  155.         *sigStatePtr = SIG_IGNORING;
  156.     } else if (pcbPtr->sigActions[spriteSig] > SIG_NUM_ACTIONS) {
  157.         *sigStatePtr = SIG_HANDLING;
  158.     } else if (pcbPtr->sigHoldMask & spriteSig) {
  159.         *sigStatePtr = SIG_HOLDING;
  160.     } else {
  161.         *sigStatePtr = 0;
  162.     }
  163.  
  164.    }
  165.    return (procState);
  166.  
  167. }
  168.  
  169. /*
  170.  *----------------------------------------------------------------------
  171.  *
  172.  *  XferSegmentFromProcess --
  173.  *
  174.  *      Transfer a memory segment from a process into a file. 
  175.  *
  176.  *     This routines transfers the memory image from the process 
  177.  *    specified by pid into the file coreFile. The transfer starts
  178.  *    at the address specified by startAddress and ends on the first
  179.  *    unreadable page. 
  180.  *
  181.  * Results:
  182.  *    Number of bytes written to file. -1 if an error occured.
  183.  *
  184.  * Side effects:
  185.  *      The file is written.
  186.  *
  187.  *----------------------------------------------------------------------
  188.  */
  189.  
  190. int
  191. XferSegmentFromProcess(pid,startAddress,coreFile)
  192.     int          pid;        /* Process ID to operate on. */
  193.     unsigned int startAddress;    /* Address to start with. */
  194.     FILE    *coreFile;    /* File to write image to. */
  195. {
  196.     ReturnStatus                status = SUCCESS;
  197.     int                numPages, xferSize = getpagesize();
  198.     char            *xferBuffer;
  199.     unsigned int        nextAddress;
  200.  
  201.     /*
  202.      * Round the starting address to point at the start of its page.
  203.      */
  204.  
  205.     startAddress = startAddress & ~(xferSize-1);
  206.     nextAddress = startAddress;
  207.     if (debug) {
  208.       fprintf (stderr,"Xfering memory from process %d...\n", pid);
  209.       fprintf (stderr,"Start Address: %d\n", startAddress);
  210.     }
  211.     /*
  212.      * Allocate the buffer to copy.
  213.      */
  214.     xferBuffer = malloc(xferSize);
  215.     /*
  216.      * Read from memory and write to file until we get an error.
  217.      */
  218.     numPages = 1;
  219.     status = Proc_Debug((Proc_PID)pid,PROC_READ, xferSize, 
  220.                 (char *)nextAddress,xferBuffer);
  221.     while (status == SUCCESS) {
  222.         numPages++;
  223.     if (fwrite(xferBuffer,xferSize,1,coreFile) != 1) {
  224.         perror(PROGRAM_NAME);
  225.         return (-1);
  226.     }
  227.     nextAddress += xferSize;
  228.     status = Proc_Debug((Proc_PID) pid,PROC_READ,xferSize,
  229.                 (char *)nextAddress,xferBuffer);
  230.     }
  231.     if (debug) {
  232.       fprintf (stderr,"%d pages transferred...\n", numPages);
  233.       (void) fprintf(stderr,"XferSegment 0x%x - 0x%x from 0x%x\n",
  234.              startAddress,nextAddress, pid);
  235.     }
  236.     /*
  237.      * Return the number of bytes transfered.
  238.      */
  239.     return (nextAddress-startAddress);
  240. }
  241.  
  242.  
  243. /*
  244.  *----------------------------------------------------------------------
  245.  *
  246.  *  ReadStopInfoFromProcess --
  247.  *
  248.  *      Read the stop info (ie registers and fault code) from
  249.  *    the specified process.
  250.  *
  251.  * Results:
  252.  *    True if operation succeeded false otherwise.
  253.  *
  254.  * Side effects:
  255.  *      The process is "attached" using the Proc_Debug call.
  256.  *
  257.  *----------------------------------------------------------------------
  258.  */
  259.  
  260.  
  261. Boolean
  262. ReadStopInfoFromProcess(pid,signalNumPtr,regsPtr)
  263.     int        pid;        /* Process ID to read. */
  264.     int        *signalNumPtr;    /* Signal number of fault. */
  265.     struct    regs *regsPtr;  /* Regs of process.     */
  266. {
  267.     ReturnStatus    status;
  268.     Proc_DebugState process_state;
  269.  
  270.     /*
  271.      * Attach the process.
  272.      */
  273.     if (debug) {
  274.       fprintf (stderr,"Getting regs and signal from process...\n");
  275.     }
  276.     status = Proc_Debug((Proc_PID)pid,PROC_GET_THIS_DEBUG,0,(char *)0,
  277.                         (char *)0);
  278.     if (status != SUCCESS) {
  279.     (void) fprintf(stderr, "%s: Can't attach process 0x%x error: %s", 
  280.             PROGRAM_NAME, pid, Stat_GetMsg(status));
  281.  
  282.     return FALSE;
  283.     }
  284.     /*
  285.      * Read the process's stop state.
  286.      */
  287.     status = Proc_Debug((Proc_PID)pid, PROC_GET_DBG_STATE, 0,
  288.                     (char *)0,(char *)&process_state);
  289.     if (status != SUCCESS) {
  290.     (void) fprintf(stderr, "%s: Read state of process 0x%x error: %s", 
  291.             PROGRAM_NAME, pid, Stat_GetMsg(status));
  292.  
  293.     return FALSE;
  294.     }
  295.     /*
  296.      * Map the Sprite signal to a Unix style signal using a routine 
  297.      * in libc.a.
  298.      */
  299.     (void)Compat_SpriteSignalToUnix(process_state.termStatus,signalNumPtr);
  300.     /*
  301.      * Convert the Mach_RegState structure return by Proc_Debug into a
  302.      * Unix "struct regs".
  303.      */
  304.     if (debug) {
  305.       fprintf (stderr,"Converting regs...\n");
  306.     }
  307.     ConvertSpriteRegsToUnixRegs(&process_state.regState,regsPtr);
  308.     return (TRUE);
  309. }
  310.  
  311. Boolean
  312. AttachProcess(pid)
  313. {
  314.     ReturnStatus    status;
  315.     /*
  316.      * Attach the process.
  317.      */
  318.     status = Proc_Debug((Proc_PID)pid,PROC_GET_THIS_DEBUG,0,(char *)0,
  319.                         (char *)0);
  320.     if (status != SUCCESS) {
  321.     (void) fprintf(stderr, 
  322.             "%s: Error attaching process %x: %s\n", PROGRAM_NAME,
  323.             pid, Stat_GetMsg(status));
  324.  
  325.     return FALSE;
  326.     }
  327.     return TRUE;
  328. }
  329.  
  330. Boolean
  331. DetachProcess(pid)
  332. {
  333.     ReturnStatus    status;
  334.     /*
  335.      * Attach the process.
  336.      */
  337.     status = Proc_Debug((Proc_PID)pid,PROC_DETACH_DEBUGGER,0,(char *)0,
  338.                                  (char *)0);
  339.     if (status != SUCCESS) {
  340.     if (status != PROC_INVALID_PID) { 
  341.         (void) fprintf(stderr, 
  342.             "%s: Error detaching process %x: %s\n", PROGRAM_NAME,
  343.             pid, Stat_GetMsg(status));
  344.     }
  345.     return FALSE;
  346.     }
  347.     return TRUE;
  348. }
  349.  
  350. ConvertSpriteRegsToUnixRegs(spriteRegsPtr,regsPtr)
  351. Mach_RegState    *spriteRegsPtr;
  352. struct    regs    *regsPtr;
  353. {
  354.     /* Mach_RegState defined in kernel/machTypes.h */
  355.     bcopy((char *)spriteRegsPtr->ins,(char *)&(regsPtr->r_o0),
  356.       8*sizeof(unsigned int));
  357.     regsPtr->r_y = spriteRegsPtr->y;
  358.     bcopy((char *)spriteRegsPtr->globals,(char *)&(regsPtr->r_g1),
  359.       7*sizeof(unsigned int));
  360.     /*assume r_sr changed to r_psr in struct regs and statusReg */
  361.     /*changed to curPsr */
  362.     regsPtr->r_psr = spriteRegsPtr->curPsr;
  363.     regsPtr->r_pc = spriteRegsPtr->pc;
  364. }
  365.